"""
视频管理API端点
"""
import os
import uuid
import logging
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, Query
from fastapi.responses import FileResponse
from sqlalchemy.orm import Session
from app.api.v1.schemas.video import (
    VideoUploadRequest, VideoUploadResponse, VideoTaskResponse,
    VideoTaskListResponse, PlatformTemplateResponse
)
from app.db.session import get_db
from app.models.video_task import VideoTask
from app.models.platform_template import PlatformTemplate
from app.core.storage.storage_manager import StorageManager
from app.tasks.video_tasks import process_video_task
from app.exceptions import FileUploadError, VideoProcessingError
from app.config import settings

logger = logging.getLogger(__name__)

router = APIRouter()


@router.post("/upload", response_model=VideoUploadResponse)
async def upload_video(
    title: str = Form(...),
    description: Optional[str] = Form(None),
    target_platform: str = Form(...),
    video_file: UploadFile = File(...),
    db: Session = Depends(get_db)
):
    """
    上传视频并创建处理任务
    """
    try:
        # 验证文件
        if not video_file.filename:
            raise FileUploadError("未选择视频文件")

        # 检查文件格式
        file_extension = os.path.splitext(video_file.filename)[1][1:].lower()
        if file_extension not in settings.SUPPORTED_VIDEO_FORMATS:
            raise FileUploadError(f"不支持的视频格式: {file_extension}")

        # 检查文件大小
        if video_file.size and video_file.size > settings.MAX_VIDEO_SIZE_MB * 1024 * 1024:
            raise FileUploadError(f"文件大小超过限制: {settings.MAX_VIDEO_SIZE_MB}MB")

        # 生成任务ID
        task_id = uuid.uuid4()

        # 创建任务记录
        video_task = VideoTask(
            id=task_id,
            user_id=1,  # TODO: 从认证中获取用户ID
            title=title,
            description=description,
            original_filename=video_file.filename,
            original_file_size=video_file.size,
            target_platform=target_platform,
            status="pending"
        )

        db.add(video_task)
        db.commit()
        db.refresh(video_task)

        # 保存文件到存储
        storage_manager = StorageManager()
        file_path = f"videos/originals/{task_id}/{video_file.filename}"

        try:
            # 上传文件
            file_content = await video_file.read()
            file_url = await storage_manager.upload_file(
                content=file_content,
                file_path=file_path,
                content_type=video_file.content_type
            )

            # 更新任务记录
            video_task.original_file_url = file_url
            db.commit()

        except Exception as e:
            logger.error(f"Failed to upload file: {e}")
            db.delete(video_task)
            db.commit()
            raise FileUploadError(f"文件上传失败: {e}")

        # 启动异步处理任务
        try:
            process_video_task.delay(str(task_id))
        except Exception as e:
            logger.error(f"Failed to start processing task: {e}")
            video_task.status = "failed"
            video_task.error_message = "任务启动失败"
            db.commit()
            raise VideoProcessingError("任务启动失败，请稍后重试")

        logger.info(f"Video task created successfully: {task_id}")
        return VideoUploadResponse(
            task_id=task_id,
            message="视频上传成功，开始处理..."
        )

    except FileUploadError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except VideoProcessingError as e:
        raise HTTPException(status_code=422, detail=str(e))
    except Exception as e:
        logger.error(f"Upload video failed: {e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")


@router.get("/tasks/{task_id}", response_model=VideoTaskResponse)
async def get_video_task(
    task_id: uuid.UUID,
    db: Session = Depends(get_db)
):
    """获取视频任务详情"""
    task = db.query(VideoTask).filter(VideoTask.id == task_id).first()
    if not task:
        raise HTTPException(status_code=404, detail="任务不存在")

    return VideoTaskResponse.from_orm(task)


@router.get("/tasks", response_model=VideoTaskListResponse)
async def get_video_tasks(
    page: int = Query(1, ge=1, description="页码"),
    size: int = Query(20, ge=1, le=100, description="每页数量"),
    status: Optional[str] = Query(None, description="任务状态筛选"),
    db: Session = Depends(get_db)
):
    """获取视频任务列表"""
    query = db.query(VideoTask)

    # 状态筛选
    if status:
        query = query.filter(VideoTask.status == status)

    # 分页
    total = query.count()
    offset = (page - 1) * size
    tasks = query.order_by(VideoTask.created_at.desc()).offset(offset).limit(size).all()

    return VideoTaskListResponse(
        tasks=[VideoTaskResponse.from_orm(task) for task in tasks],
        total=total,
        page=page,
        size=size
    )


@router.get("/download/{task_id}")
async def download_video(
    task_id: uuid.UUID,
    db: Session = Depends(get_db)
):
    """下载处理后的视频"""
    task = db.query(VideoTask).filter(VideoTask.id == task_id).first()
    if not task:
        raise HTTPException(status_code=404, detail="任务不存在")

    if task.status != "completed":
        raise HTTPException(status_code=400, detail="视频处理未完成")

    if not task.output_video_url:
        raise HTTPException(status_code=404, detail="输出视频文件不存在")

    try:
        # 从存储获取文件
        storage_manager = StorageManager()
        local_path = await storage_manager.download_file(task.output_video_url)
        return FileResponse(
            path=local_path,
            filename=f"{task.title}_{task.target_platform}.mp4",
            media_type="video/mp4"
        )
    except Exception as e:
        logger.error(f"Failed to download video: {e}")
        raise HTTPException(status_code=500, detail="文件下载失败")


@router.get("/preview/{task_id}")
async def preview_video(
    task_id: uuid.UUID,
    db: Session = Depends(get_db)
):
    """预览视频"""
    task = db.query(VideoTask).filter(VideoTask.id == task_id).first()
    if not task:
        raise HTTPException(status_code=404, detail="任务不存在")

    if task.status != "completed":
        raise HTTPException(status_code=400, detail="视频处理未完成")

    if not task.output_video_url:
        raise HTTPException(status_code=404, detail="输出视频文件不存在")

    return {
        "task_id": task_id,
        "video_url": task.output_video_url,
        "thumbnail_url": task.thumbnail_url,
        "duration": task.duration,
        "title": task.title,
        "platform": task.target_platform
    }


@router.get("/templates", response_model=List[PlatformTemplateResponse])
async def get_platform_templates(db: Session = Depends(get_db)):
    """获取平台模板列表"""
    templates = db.query(PlatformTemplate).filter(
        PlatformTemplate.is_active == True
    ).order_by(PlatformTemplate.platform_name).all()

    return [PlatformTemplateResponse.from_orm(template) for template in templates]


@router.delete("/tasks/{task_id}")
async def delete_video_task(
    task_id: uuid.UUID,
    db: Session = Depends(get_db)
):
    """删除视频任务"""
    task = db.query(VideoTask).filter(VideoTask.id == task_id).first()
    if not task:
        raise HTTPException(status_code=404, detail="任务不存在")

    # 只允许删除已完成或失败的任务
    if task.status not in ["completed", "failed"]:
        raise HTTPException(status_code=400, detail="只能删除已完成或失败的任务")

    try:
        # 删除存储的文件
        storage_manager = StorageManager()
        if task.original_file_url:
            await storage_manager.delete_file(task.original_file_url)
        if task.output_video_url:
            await storage_manager.delete_file(task.output_video_url)
        if task.thumbnail_url:
            await storage_manager.delete_file(task.thumbnail_url)

        # 删除数据库记录
        db.delete(task)
        db.commit()

        return {"message": "任务删除成功"}

    except Exception as e:
        logger.error(f"Failed to delete task: {e}")
        raise HTTPException(status_code=500, detail="删除失败")


@router.post("/tasks/{task_id}/retry")
async def retry_video_task(
    task_id: uuid.UUID,
    db: Session = Depends(get_db)
):
    """重试失败的视频任务"""
    task = db.query(VideoTask).filter(VideoTask.id == task_id).first()
    if not task:
        raise HTTPException(status_code=404, detail="任务不存在")

    if task.status != "failed":
        raise HTTPException(status_code=400, detail="只能重试失败的任务")

    # 重置任务状态
    task.status = "pending"
    task.progress = 0.0
    task.current_step = None
    task.error_message = None
    task.error_details = None
    db.commit()

    # 重新启动处理任务
    try:
        process_video_task.delay(str(task_id))
    except Exception as e:
        logger.error(f"Failed to retry task: {e}")
        task.status = "failed"
        task.error_message = "任务重试启动失败"
        db.commit()
        raise VideoProcessingError("任务重试失败，请稍后重试")

    return {"message": "任务重试成功"}